﻿using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;

namespace Sublimation
{
    public abstract class Projectile : GameObject
    {
        #region Attributes
        protected int NUMBER_OF_FRAMES_TO_PLAY = 8;
        protected const int FRAMES_PER_SECOND = 20;
        protected float aerodynamism = 0.99f;
        protected int chargeTime;
        protected int maxChargeTime = 550;
        protected bool isFriendly;
        public bool IsFriendly
        {
            get { return this.isFriendly; }
            set { this.isFriendly = value; }
        }

        protected float damagePotential;
        public float DamagePotential
        {
            get { return this.damagePotential; }
            set { this.damagePotential = value; }
        }

        protected Vector2 size;
        protected Vector2 initial_position;
        protected float range;

        protected Rectangle area;
        #endregion


        public Projectile(WorldProperties worldProperties, bool isFriendly, Vector2 position, Vector2 velocity, float maxSpeed, Vector2 size, float range, float damagePotential)
            : base(worldProperties)
        {
            MaxSpeed = maxSpeed;
            LoadContent();

            // make sure it loads and draws
            DrawOrder = 80;
            UpdateOrder = 50;
            Visible = true;
            Enabled = true;

            SetOriginToCentre();
            this.size = size;
            this.isFriendly = isFriendly;

            this.velocity = velocity;
            this.velocity.Normalize();
            this.velocity *= MaxSpeed;

            this.Rotation = (float)Math.Atan2(Velocity.Y, Velocity.X);
            this.initial_position = position;
            this.position = position;
            this.range = range;
            this.damagePotential = damagePotential;
            CollisionRadius = 10;
            Visible = true;
            this.Rotation = (float)Math.Acos(Vector2.Dot(Vector2.UnitX, Velocity) / Velocity.Length()) * Math.Sign(Vector2.Dot(Vector2.UnitY, Velocity));

        }



        public override void DoMovement(GameTime gameTime)
        {

            base.DoMovement(gameTime);
        }

        protected override void SetupBehaviours()
        {
            base.SetupBehaviours();
            this.behaviours.Add(new Behaviours.BulletFrictionBehavior(worldProperties, this, aerodynamism));
        }

        public void SelfDestruct()
        {
            // kill without impacting anything
            // if we killed without impacting something, draw a scorch mark on the map
            worldProperties.DrawScorchMark(Position, CollisionRadius * 3.5f);
            Kill();
        }

        public override void CheckCollisions(GameTime gameTime)
        {
            base.CheckCollisions(gameTime);

            //TODO: physical objects
            
            foreach (Rectangle rectangle in worldProperties.Map.PhysicalObjects)
            {
                if(rectangle.Intersects(BoundingRectangle)){
                    Kill();
                }
            }

            // Towers, only do damage if not friendly bullet
            foreach (Player player in worldProperties.Players)
            {
                foreach (Tower tower in player.Towers)
                {
                    if (CollidesWith(tower))
                    {
                        Kill();
                        if (!IsFriendly) tower.ApplyDamage(DamagePotential);
                        ExplosionAnimation(tower);
                        return;
                    }
                }
            }

            // Units
            if (IsFriendly)
            {
                // collide with enemy units
                foreach (EnemyUnit unit in worldProperties.Enemies)
                {
                    if (CollidesWith(unit))
                    {
                        Kill();
                        unit.ApplyDamage(DamagePotential);
                        ExplosionAnimation(unit);
                        return;
                    }
                }
            }
            else
            {
                // collide with friendly units
                foreach (Player player in worldProperties.Players)
                {
                    foreach (Unit unit in player.Units)
                    {
                        if (CollidesWith(unit))
                        {
                            Kill();
                            unit.ApplyDamage(DamagePotential);
                            return;
                        }
                    }
                }
            }
        }

        protected abstract void ExplosionAnimation(GameObject target);

        protected override void LoadContent()
        {
            base.LoadContent();
            Sprite = Game.Content.Load<Texture2D>("Sprites/fireball");
            Scale = 1.0f;
        }
    }
}
